package com.xc.pay.weixin.util;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONObject;
import com.wechat.pay.contrib.apache.httpclient.Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.Signer;
import com.xc.pay.common.MessageTemplate;
import com.xc.pay.weixin.constant.WxProperties;
import com.xc.pay.weixin.properties.base.WxPayBaseProperties;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpRequestWrapper;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.security.Signature;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * Filename: WxToolUtil.java <br>
 *
 * <p>Description: 微信支付公共util<br>
 *
 * @author: rongrong <br>
 * @version: 1.0 <br>
 */
public class WxToolUtil {

  private static final String UNKNOWN = "unknown";

  /**
   * 获取时间戳
   *
   * @return String
   */
  public static String getTimestamp() {
    return System.currentTimeMillis() / 1000 + "";
  }

  /**
   * 获取随机字符串
   *
   * @return String
   */
  public static String getNonceStr() {
    return IdUtil.simpleUUID();
  }

  /**
   * 获取客户端的ip地址
   *
   * @return String
   */
  public static String getIpAddress() {
    try {
      HttpServletRequest request =
          ((ServletRequestAttributes)
                  Objects.requireNonNull(RequestContextHolder.getRequestAttributes()))
              .getRequest();
      String ip = request.getHeader("x-forwarded-for");
      if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
        ip = request.getHeader("Proxy-Client-IP");
      }
      if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
        ip = request.getHeader("WL-Proxy-Client-IP");
      }
      if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
        ip = request.getHeader("HTTP_CLIENT_IP");
      }
      if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
        ip = request.getHeader("HTTP_X_FORWARDED_FOR");
      }
      if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
        ip = request.getRemoteAddr();
      }
      return ip;
    } catch (Exception e) {
      return null;
    }
  }

  /**
   * 微信APP支付失败返回
   *
   * @return String
   */
  public static String success() {
    Map<String, String> returnData = new HashMap<>(2);
    // 支付失败
    returnData.put("return_code", "SUCCESS");
    returnData.put("return_msg", "支付成功");
    return XMLUtil.GetMapToXML(returnData);
  }

  /**
   * 微信APP支付失败返回
   *
   * @param msg 异常信息
   * @return String
   */
  public static String fail(String msg) {
    Map<String, String> returnData = new HashMap<>(2);
    // 支付失败
    returnData.put("return_code", "FAIL");
    returnData.put("return_msg", msg);
    return XMLUtil.GetMapToXML(returnData);
  }

  /**
   * 参数校验
   *
   * @param properties 公共参数信息
   */
  public static void checkArgs(WxPayBaseProperties properties) {
    /* apiV3秘钥值 */
    final String apiV3Key = properties.getApiV3Key();
    Assert.notBlank(apiV3Key, MessageTemplate.ERROR_TEMPLATE, "apiV3Key");
    /* 证书序列号 */
    final String mchSerialNumber = properties.getCertSerialNumber();
    Assert.notBlank(mchSerialNumber, MessageTemplate.ERROR_TEMPLATE, "mchSerialNumber");
    /* p12证书文件的绝对路径或者以classpath:开头的类路径 */
    final String keyPath = properties.getKeyPath();
    Assert.notBlank(keyPath, MessageTemplate.ERROR_TEMPLATE, "keyPath");
    /* apiclient_key.pem证书文件的绝对路径或者以classpath:开头的类路径 */
    final String privateKeyPath = properties.getPrivateKeyPath();
    Assert.notBlank(privateKeyPath, MessageTemplate.ERROR_TEMPLATE, "privateKeyPath");
    /* apiclient_cert.pem证书文件的绝对路径或者以classpath:开头的类路径 */
    final String privateCertPath = properties.getPrivateCertPath();
    Assert.notBlank(privateCertPath, MessageTemplate.ERROR_TEMPLATE, "privateCertPath");
  }

}
